﻿// ----------------------------------------------------------------------------
//  Copyright (C) 成都联宇创新科技有限公司 版权所有。 
//      
//  文件名：Repository.cs
//  文件功能描述：
//  创建标识：骆智慧 2016/03/04 11:37
//     
//  修改标识：骆智慧  2016/03/10/06:27
//  修改描述：
//  ----------------------------------------------------------------------------

#region 导入名称空间

using System;
using Autofac.Interceptor;
using LightWork.DomainModel;
using LightWork.Interceptor;
using NHibernate;
using NHibernate.Context;

#endregion

namespace LightWork.DataAccess
{
    [Intercept(typeof (LogInterceptor))]
    public abstract class Repository<T, TEntityKey> : IReadOnlyRepository<T, TEntityKey>
        where T : class, IAggregateRoot
    {
        private readonly ISessionFactory _sesionFactory;
        private readonly object syncLock = new object();

        protected Repository(ISessionFactory sessionFactory)
        {
            if (sessionFactory == null)
            {
                throw new ArgumentNullException(nameof(sessionFactory));
            }
            _sesionFactory = sessionFactory;
            BindSession();
        }

        public IQueryOver<T, T> QueryOver
        {
            get
            {
                BindSession();
                return _sesionFactory.GetCurrentSession().QueryOver<T>();
            }
        }

        public T FindById(TEntityKey id)
        {
            return _sesionFactory.GetCurrentSession().Load<T>(id);
        }

        private void BindSession()
        {
            lock (syncLock)
            {
                if (!CurrentSessionContext.HasBind(_sesionFactory))
                {
                    var session = _sesionFactory.OpenSession();
                    CurrentSessionContext.Bind(session);
                }
            }
        }

        public void Add(T entity)
        {
            _sesionFactory.GetCurrentSession().Save(entity);
        }

        public void Remove(T entity)
        {
            _sesionFactory.GetCurrentSession().Delete(entity);
        }

        public void Save(T entity)
        {
            _sesionFactory.GetCurrentSession().SaveOrUpdate(entity);
        }

        //public T FindBy(TEntityKey id)
        //{
        //	return _sesionFactory.GetCurrentSession().Get<T>(id);
        //}

        //public IEnumerable<T> FindAll()
        //{
        //	var criteriaQuery = _sesionFactory.GetCurrentSession().CreateCriteria(typeof (T));

        //	return (List<T>) criteriaQuery.List<T>();

        //}

        //public Paging<T> FindAll(int currentPage, int count)
        //{
        //	var paging = new Paging<T>(currentPage, count);
        //	var criteria = _sesionFactory.GetCurrentSession().CreateCriteria(typeof (T));
        //	criteria.SetProjection(Projections.RowCount());
        //	paging.TotalRecord = Convert.ToInt32(criteria.UniqueResult().ToString());
        //	criteria.SetProjection(null);

        //	criteria.SetFirstResult(paging.PageIndex);
        //	criteria.SetMaxResults(paging.PageSize);
        //	paging.Records = criteria.List<T>();

        //	return paging;
        //}

        //public IEnumerable<T> FindBy(params ICriterion[] criterions)
        //{
        //	var criteria = _sesionFactory.GetCurrentSession().CreateCriteria<T>();
        //	foreach (var criterion in criterions)
        //	{
        //		criteria.Add(criterion);
        //	}

        //	return criteria.List<T>();
        //}

        //public Paging<T> FindBy(int currentPage, int count, params ICriterion[] criterions)
        //{
        //	var paging = new Paging<T>(currentPage, count);

        //	var criteria = _sesionFactory.GetCurrentSession().CreateCriteria(typeof (T));
        //	foreach (var criterion in criterions)
        //	{
        //		criteria.Add(criterion);
        //	}
        //	criteria.SetProjection(Projections.RowCount());
        //	paging.TotalRecord = Convert.ToInt32(criteria.UniqueResult().ToString());
        //	criteria.SetProjection(null);

        //	criteria.SetFirstResult(paging.PageIndex);
        //	criteria.SetMaxResults(paging.PageSize);
        //	paging.Records = criteria.List<T>();

        //	return paging;
        //}
    }
}